import { Body, Controller, Delete, Get, Post, Put, Query } from '@nestjs/common'
import { ApiOperation, ApiTags } from '@nestjs/swagger'

import { ApiResult } from '~/common/decorators/api-result.decorator'
import { ApiSecurityAuth } from '~/common/decorators/swagger.decorator'
import { DeleteDto } from '~/common/dto/delete.dto'
import { BusinessException } from '~/common/exceptions/biz.exception'
import { CreatorPipe } from '~/common/pipes/creator.pipe'
import { UpdaterPipe } from '~/common/pipes/updater.pipe'
import { ErrorEnum } from '~/constants/error-code.constant'
import { AuthUser } from '~/modules/system/auth/decorators/auth-user.decorator'
import { definePermission, Perm } from '~/modules/system/auth/decorators/permission.decorator'
import { DeptEntity } from '~/modules/system/dept/dept.entity'

import { DeptQueryDto, DeptSaveDto, DeptSimpleDto } from './dept.dto'
import { DeptService } from './dept.service'

export const permissions = definePermission('system:dept', {
  LIST: 'list',
  QUERY: 'query',
  CREATE: 'create',
  UPDATE: 'update',
  DELETE: 'delete',
} as const)

@ApiSecurityAuth()
@ApiTags('System - 部门模块')
@Controller('dept')
export class DeptController {
  constructor(private deptService: DeptService) {}

  @Get('list')
  @ApiOperation({ summary: '获取部门列表' })
  @ApiResult({ type: [DeptEntity] })
  @Perm(permissions.LIST)
  async list(@Query() dto: DeptQueryDto, @AuthUser('uid')uid: number): Promise<DeptEntity[]> {
    return this.deptService.getDeptTree(uid, dto)
  }

  @Get('simple-list')
  @ApiOperation({ summary: '获取部门简单列表' })
  @ApiResult({ type: [DeptSimpleDto] })
  @Perm(permissions.LIST)
  async simpleList(): Promise<DeptSimpleDto[]> {
    return this.deptService.getSimpleList()
  }

  @Get('get')
  @ApiOperation({ summary: '查询部门详情' })
  @ApiResult({ type: DeptEntity })
  @Perm(permissions.QUERY)
  async get(@Query('id') id: number) {
    return this.deptService.info(id)
  }

  @Post('create')
  @ApiOperation({ summary: '创建部门' })
  @Perm(permissions.CREATE)
  async create(@Body(CreatorPipe) dto: DeptSaveDto): Promise<void> {
    await this.deptService.create(dto)
  }

  @Put('update')
  @ApiOperation({ summary: '更新部门' })
  @Perm(permissions.UPDATE)
  async update(@Body(UpdaterPipe) dto: DeptSaveDto): Promise<void> {
    if (!dto.id) {
      throw new BusinessException(ErrorEnum.DEPARTMENT_NOT_FOUND)
    }
    await this.deptService.update(dto.id, dto)
  }

  @Delete('delete')
  @ApiOperation({ summary: '删除部门' })
  @Perm(permissions.DELETE)
  async delete(@Query() dto: DeleteDto): Promise<void> {
    // 解析ids参数，支持单个和多个删除
    const ids = dto.ids.split(',').map(id => Number.parseInt(id.trim())).filter(id => !Number.isNaN(id))

    if (ids.length === 0) {
      throw new BusinessException(ErrorEnum.DEPARTMENT_NOT_FOUND)
    }

    // 批量删除
    for (const id of ids) {
      // 查询是否有关联用户或者部门，如果含有则无法删除
      const count = await this.deptService.countUserByDeptId(id)
      if (count > 0)
        throw new BusinessException(ErrorEnum.DEPARTMENT_HAS_ASSOCIATED_USERS)

      const count2 = await this.deptService.countChildDept(id)
      if (count2 > 0)
        throw new BusinessException(ErrorEnum.DEPARTMENT_HAS_CHILD_DEPARTMENTS)

      await this.deptService.delete(id)
    }
  }
}
